import datetime
from package.fastapi.uuid7 import uuid7_hex
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy import Column, String, DateTime, Boolean, ForeignKey, Integer, BigInteger
from sqlalchemy.orm import relationship


Base = declarative_base()


class Devops(Base):
    """运维对象"""
    __tablename__ = 'devops'
    id = Column(String, primary_key=True, default=uuid7_hex, comment='主键ID')
    name = Column(String, unique=True, comment='名称')
    category = Column(String, nullable=False, comment='运维对象类型')
    description = Column(String, nullable=False, comment='运维对象描述')

    host = Column(String, nullable=False, comment='IP/域名')
    port = Column(Integer, nullable=True, comment='端口')

    configure = Column(JSONB, default={}, comment='连接信息/认证信息')
    heartbeat_interval = Column(Integer, default=0, comment='心跳检查/m')
    metric_interval = Column(Integer, default=0, comment='指标监控/m')
    extra = Column(JSONB, default={}, comment='额外运维信息 机房/机架/XXX')
    created_at = Column(DateTime, default=datetime.datetime.utcnow, comment='创建时间')
    updated_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow, comment='更新时间')


class SourceInterrupt(Base):
    """数据源中断周期检查"""
    __tablename__ = 'source_interrupt'
    id = Column(String, primary_key=True, comment='主键ID')
    interrupt = Column(Integer, default=0, comment='中断检查周期')
    notify = Column(JSONB, default=None, comment='中断通知')


class SourceStatistic(Base):
    """数据源 数据统计"""
    __tablename__ = 'statistic_source'
    id = Column(String, primary_key=True, comment='主键ID')
    first_at = Column(BigInteger, nullable=True, comment='最早接收')
    last_at = Column(BigInteger, nullable=True, comment='最近接收')
    count = Column(BigInteger, default=0, comment='接收数量')


class StatisticDsm(Base):
    """数据 源->模型 数据统计"""
    __tablename__ = 'statistic_dsm'
    id = Column(String, primary_key=True, comment='主键ID')
    first_at = Column(BigInteger, nullable=True, comment='最早接收')
    last_at = Column(BigInteger, nullable=True, comment='最近接收')

    source_id = Column(String, comment='数据源ID')
    model_id = Column(String, comment='模型ID')
    model_postfix = Column(String, comment='模型后缀-000001')
    count = Column(BigInteger, default=0, comment='接收数量')


class StatisticModel(Base):
    """数据 源->模型 数据统计"""
    __tablename__ = 'statistic_model'
    id = Column(String, primary_key=True, comment='主键ID')
    model_id = Column(String, comment='模型ID')
    count = Column(BigInteger, default=0, comment='模型数量')
    size = Column(BigInteger, default=0, comment='磁盘消耗')


class Source(Base):
    """数据源"""
    __tablename__ = 'source'
    id = Column(String, primary_key=True, default=uuid7_hex, comment='主键ID')

    category = Column(String, nullable=False, comment='数据源采集类型')
    name = Column(String, unique=True, comment='数据源名称')
    description = Column(String, nullable=False, comment='数据源描述')
    host = Column(String, nullable=False, comment='IP/域名')
    port = Column(Integer, nullable=True, comment='端口')
    configure = Column(JSONB, default={}, comment='数据源认证与连接')
    cron = Column(JSONB, default=None, comment='采集周期')
    
    rule_groups = relationship('ETLGroup', secondary='source_group_relate', lazy='dynamic', backref='sources')
    interrupt = Column(JSONB, default=None, comment='中断检查配置')


class ETLLib(Base):
    """解析通用库"""
    __tablename__ = 'etl_lib'
    id = Column(String, primary_key=True, default=uuid7_hex, comment='主键ID')
    name = Column(String, comment='解析名称')
    inner = Column(Boolean, default=False, comment='内置')
    
    pipeline = Column(JSONB, default=None, comment='解析流程')
    
    created_at = Column(DateTime, default=datetime.datetime.utcnow, comment='创建时间')
    updated_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow, comment='更新时间')


class ETLMap(Base):
    """解析字典"""
    __tablename__ = 'etl_map'
    name = Column(String, comment='解析字典名称')
    inner = Column(Boolean, default=False, comment='内置')
    configure = Column(JSONB, default={}, comment='映射表')
    created_at = Column(DateTime, default=datetime.datetime.utcnow, comment='创建时间')
    updated_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow, comment='更新时间')


class ETLRule(Base):
    """解析规则"""
    __tablename__ = 'etl_rule'
    id = Column(String, primary_key=True, default=uuid7_hex, comment='主键ID')
    group_id = Column(String, ForeignKey('ETLGroup.id'), comment='分组ID')
    name = Column(String, comment='解析名称')
    inner = Column(Boolean, default=False, comment='内置')

    pipeline = Column(JSONB, default=None, comment='解析流程')
    priority = Column(Integer, default=100, comment='优先级')
    
    created_at = Column(DateTime, default=datetime.datetime.utcnow, comment='创建时间')
    updated_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow, comment='更新时间')


class ETLGroup(Base):
    __tablename__ = 'rulegroup'
    id = Column(String, primary_key=True, default=uuid7_hex, comment='主键ID')
    name = Column(String, comment='解析规则组')
    rules = relationship('ETLRule', order_by=ETLRule.created_at.desc, backref='group')


class ETLModel(Base):
    """数据模型"""
    __tablename__ = 'etl_model'
    id = Column(String, primary_key=True, default=uuid7_hex, comment='主键ID')
    name = Column(String, comment='模型名称')
    inner = Column(Boolean, default=False, comment='内置')
    fields = Column(JSONB, default=[], comment='字段')
    rules = relationship('ETLRule', order_by=ETLRule.created_at.desc, backref='model')


class SourceETLRelate(Base):
    """数据解析工作流"""
    __tablename__ = 'source_rulegroup_relate'
    id = Column(String, primary_key=True, default=uuid7_hex, comment='主键ID')
    source_id = Column(String, ForeignKey("source.id", ondelete='CASCADE'), comment='数据源ID')
    rulegroup_id = Column(String, ForeignKey("rule_group.id", ondelete='CASCADE'), comment='规则组ID')
